package com.wzh.project.asm.main;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.*;

import java.io.FileOutputStream;

/**
 * asm动态生成的主类
 */
public class AsmMain {
    private static final Logger logger = LogManager.getLogger(AsmMain.class);
    public static void main(String[] args) throws Exception {
        logger.debug("开始执行");
        ClassWriter cw = new ClassWriter(0);


        //创建对应的类
        String className="WzhDynamaicTest";

        /**
         * 1 第一个参数版本号
         * 2 第二个参数定义类的范围
         * 3 定义类的名字
         * 4 定义类的签名，为null固定值
         * 5 定义该类的父类
         * 6 如果定义的是数组，这个为数据内部的对象类型 引入的类型
         */
        cw.visit(V1_1, ACC_PUBLIC,className, null, "java/lang/Object", null);

        //创建对应的方法//创建默认的构造方法
        /**
         * 1 方法的级别
         * 2 方法的名字
         * 3 方法的签名
         * 4 抛出的异常信息
         */
        MethodVisitor mv=cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
        mv.visitCode();
		mv.visitVarInsn(ALOAD, 0);
		mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
		mv.visitInsn(RETURN);
		mv.visitMaxs(1, 1);
		mv.visitEnd();

        //创建自己的get方法
        MethodVisitor getMV=cw.visitMethod(ACC_PUBLIC,"getName","()V",null,null);
        //getMV.visitFieldInsn(opcode, owner, name, descriptor);
        //创建自己的set方法
        MethodVisitor setMV=cw.visitMethod(ACC_PUBLIC,"setName","(java/lang/String)V",null,null);

        //设置对应的字段
        cw.visitField(ACC_PUBLIC, "name", "Ljava/lang/String;", null, "wzh");
        
        
        //设置结束标志
        cw.visitEnd();
        /**
         * 写入文件
         */
        byte[] code = cw.toByteArray();
        FileOutputStream fos = new FileOutputStream(className);
        fos.write(code);
        fos.flush();
        fos.close();
        System.out.println("====end====");
    }
}
